#include "f5_open_atom_main.h"

#include <stdio.h>
#include <stdbool.h>

#include "los_task.h"
#include "ohos_init.h"
#include "cmsis_os.h"
#include "config_network.h"
#include "smart_home.h"
#include "smart_home_event.h"

#include "dev_alarm.h"
#include "su_03t.h"
#include "wifi_tcp.h"
#include "lcd.h"
#include "picture.h"
#include "adc_key.h"
#include "adc_mq2.h"

data_info_t main_data;

void open_atom_main(void)
{
    unsigned int ret = LOS_OK;

    TSK_INIT_PARAM_S Start_Task = {
        .pfnTaskEntry = (TSK_ENTRY_FUNC)Start_Task_Entry, // 任务入口函数
        .usTaskPrio = Start_Task_Prio,                    // 任务优先级
        .uwArg = Start_Task_Arg,                          // 任务参数
        .uwStackSize = Start_Task_Stack_Size,             // 任务堆栈大小
        .pcName = Start_Task_Name,                        // 任务名
        .uwResved = Start_Task_Resved,                    // 保留字段
    };
    ret = LOS_TaskCreate(&Start_thread_id, &Start_Task);
    if (ret != LOS_OK)
    {
        printf("Falied to create Task_One ret:0x%x\n", ret);
        return;
    }
}
APP_FEATURE_INIT(open_atom_main);

void Start_thread(void *arg) // 常规的线程设置
{
    unsigned int thread_id_3;
    TSK_INIT_PARAM_S task_3 = {0};
    unsigned int ret = LOS_OK;

    smart_home_event_init();

    // ret = LOS_QueueCreate("su03_queue", MSG_QUEUE_LENGTH, &m_su03_msg_queue, 0, BUFFER_LEN);
    // if (ret != LOS_OK)
    // {
    //     printf("Falied to create Message Queue ret:0x%x\n", ret);
    //     return;
    // }

    TSK_INIT_PARAM_S main_Task = {
        .pfnTaskEntry = (TSK_ENTRY_FUNC)main_Task_Entry, // 任务入口函数
        .usTaskPrio = main_Task_Prio,                    // 任务优先级
        .uwArg = main_Task_Arg,                          // 任务参数
        .uwStackSize = main_Task_Stack_Size,             // 任务堆栈大小
        .pcName = main_Task_Name,                        // 任务名
        .uwResved = main_Task_Resved,                    // 保留字段
    };
    ret = LOS_TaskCreate(&main_thread_id, &main_Task);
    if (ret != LOS_OK)
    {
        printf("Falied to create Task_One ret:0x%x\n", ret);
        return;
    }

    TSK_INIT_PARAM_S adc_key_Task = {
        .pfnTaskEntry = (TSK_ENTRY_FUNC)adc_key_Task_Entry, // 任务入口函数
        .usTaskPrio = adc_key_Task_Prio,                    // 任务优先级
        .uwArg = adc_key_Task_Arg,                          // 任务参数
        .uwStackSize = adc_key_Task_Stack_Size,             // 任务堆栈大小
        .pcName = adc_key_Task_Name,                        // 任务名
        .uwResved = adc_key_Task_Resved,                    // 保留字段
    };
    ret = LOS_TaskCreate(&adc_key_thread_id, &adc_key_Task);
    if (ret != LOS_OK)
    {
        printf("Falied to create Task_One ret:0x%x\n", ret);
        return;
    }

    TSK_INIT_PARAM_S iot_Task = {
        .pfnTaskEntry = (TSK_ENTRY_FUNC)iot_Task_Entry, // 任务入口函数
        .usTaskPrio = iot_Task_Prio,                    // 任务优先级
        .uwArg = iot_Task_Arg,                          // 任务参数
        .uwStackSize = iot_Task_Stack_Size,             // 任务堆栈大小
        .pcName = iot_Task_Name,                        // 任务名
        .uwResved = iot_Task_Resved,                    // 保留字段
    };
    ret = LOS_TaskCreate(&iot_thread_id, &iot_Task);
    if (ret != LOS_OK)
    {
        printf("Falied to create Task_One ret:0x%x\n", ret);
        return;
    }

    TSK_INIT_PARAM_S updete_Task = {
        .pfnTaskEntry = (TSK_ENTRY_FUNC)updete_Task_Entry, // 任务入口函数
        .usTaskPrio = updete_Task_Prio,                    // 任务优先级
        .uwArg = updete_Task_Arg,                          // 任务参数
        .uwStackSize = updete_Task_Stack_Size,             // 任务堆栈大小
        .pcName = updete_Task_Name,                        // 任务名
        .uwResved = updete_Task_Resved,                    // 保留字段
    };
    ret = LOS_TaskCreate(&uodete_thread_id, &updete_Task);
    if (ret != LOS_OK)
    {
        printf("Falied to create Task_One ret:0x%x\n", ret);
        return;
    }

    TSK_INIT_PARAM_S alarm_Task = {
        .pfnTaskEntry = (TSK_ENTRY_FUNC)alarm_Task_Entry, // 任务入口函数
        .usTaskPrio = alarm_Task_Prio,                    // 任务优先级
        .uwArg = alarm_Task_Arg,                          // 任务参数
        .uwStackSize = alarm_Task_Stack_Size,             // 任务堆栈大小
        .pcName = alarm_Task_Name,                        // 任务名
        .uwResved = alarm_Task_Resved,                    // 保留字段
    };
    ret = LOS_TaskCreate(&alarm_thread_id, &alarm_Task);
    if (ret != LOS_OK)
    {
        printf("Falied to create Task_One ret:0x%x\n", ret);
        return;
    }
}

/***************************************************************
 * 函数名称: smart_home_thread
 * 说    明: 智慧家居主线程
 * 参    数: 无
 * 返 回 值: 无
 ***************************************************************/
void main_thread(void *arg)
{
    tcp_data iot_data;
    double *data_ptr = NULL;

    // double illumination_range = 50.0;
    // double temperature_range = 35.0;
    // double humidity_range = 80.0;

    lcd_dev_init();   // 初始化lcd设备
    motor_dev_init(); // 初始化电机
    light_dev_init(); // 初始化rgb灯
    su03t_init();     // 初始化语音模块

    // lcd_load_ui();
    lcd_show_ui(); // 加载lcd ui

    while (1)
    {
        event_info_t event_info = {0};
        // 等待事件触发,如有触发,则立即处理对应事件,如未等到,则执行默认的代码逻辑,更新屏幕
        int ret = smart_home_event_wait(&event_info, 3000);
        if (ret == LOS_OK)
        {
            // 收到指令
            printf("event recv %d ,%d\n", event_info.event, event_info.data.iot_data);
            switch (event_info.event)
            {
            case event_key_press:
                smart_home_key_process(event_info.data.key_no);
                break;
            case event_iot_cmd:
                smart_home_iot_cmd_process(event_info.data.iot_data);
                break;
            case event_su03t:
                smart_home_su03t_cmd_process(event_info.data.su03t_data);
                break;
            case event_alarm:
                printf("alarm recv\n");
                // smart_home_ppm_cmd_process(event_info.data.alarm);
                break;
            default:
                break;
            }
        }

        if (tcp_is_connected()) // 检查网络连接
        {
            // 发送iot数据
            iot_data.illumination = main_data.illumination;
            iot_data.temperature = main_data.temperature;
            iot_data.humidity = main_data.humidity;
            iot_data.ppm = main_data.ppm;
            iot_data.light_state = get_light_state(); // 灯状态
            iot_data.motor_state = get_motor_state(); // 电机状态
            // iot_data.auto_state = auto_state;
            tcp_send_data(&iot_data);

            lcd_set_network_state(true);
        }
        else
        {
            lcd_set_network_state(false);
        }
        lcd_show_ui();
    }
}

/***************************************************************
 * 函数名称: updete_thread
 * 说    明: 数据采集线程
 * 参    数: 无
 * 返 回 值: 无
 ***************************************************************/
void updete_thread(void *args)
{
    i2c_dev_init(); // 初始化iic设备
    mq2_init();
    while (1)
    {
        sht30_read_data(&main_data.temperature, &main_data.humidity); // 读取温湿度
        bh1750_read_data(&main_data.illumination);                    // 读取光照度
        mq2_read_data(&main_data.ppm);
        mpu6050_read_data(&main_data.mpu6050);
        // printf("x %d y %d z %d \r\n", main_data.mpu6050.mpu6050_data_x,
        //        main_data.mpu6050.mpu6050_data_y,
        //        main_data.mpu6050.mpu6050_data_z);

        lcd_set_illumination(main_data.illumination); // 显示光照度
        lcd_set_temperature(main_data.temperature);   // 显示温度
        lcd_set_humidity(main_data.humidity);         // 显示湿度
        lcd_set_ppm(main_data.ppm);                   // 显示ppm值

        LOS_Msleep(500);
    }
}
void set_alarm_states(bool light_state, bool beep_state)
{
    alarm_light_set_gpio(light_state);
    beep_set_state(beep_state);
}
void alarm_thread(void *args)
{
    bool alarm_light_state = false;
    bool beep_state = false;
    bool auto_state;

    bool light_last_state = false;
    bool beep_last_state = false;

    beep_dev_init();
    alarm_light_init();

    tcp_alarm_t tcp_alarm = {0};
    event_info_t alarm_event = {0};

    while (1)
    {
        auto_state = auto_is_connected();

        if (auto_state)
        {
            if (main_data.ppm > ppm_max || main_data.humidity > humidity_max)
            {
                alarm_light_state = true;
                beep_state = true;

                set_alarm_states(true, true);

                if ((beep_state != beep_last_state) || (alarm_light_state != light_last_state))
                {
                    if (main_data.ppm > ppm_max)
                    {
                        tcp_alarm.ppm_alarm_state = true;
                        smart_home_ppm_alarm_process(&tcp_alarm);
                    }
                    if (main_data.illumination > humidity_max)
                    {
                        tcp_alarm.humidity_alarm_state = true;
                        smart_home_illumination_alarm_process(&tcp_alarm);
                    }
                    light_last_state = alarm_light_state;
                    beep_last_state = beep_state;
                    alarm_event.event = event_alarm;
                    smart_home_event_send(&alarm_event);
                }
            }
            else
            {
                alarm_light_state = false;
                beep_state = false;
                tcp_alarm.ppm_alarm_state = false;
                tcp_alarm.humidity_alarm_state = false;
                set_alarm_states(false, false);
                if ((beep_state != beep_last_state) || (alarm_light_state != light_last_state))
                {
                    smart_home_ppm_alarm_process(&tcp_alarm);
                    smart_home_illumination_alarm_process(&tcp_alarm);
                    light_last_state = alarm_light_state;
                    beep_last_state = beep_state;
                }
            }
        }
        else
        {
            set_alarm_states(alarm_light_state, beep_state);
        }
        LOS_Msleep(500);
    }
}

/***************************************************************
 * 函数名称: iot_thread
 * 说    明: iot线程
 * 参    数: 无
 * 返 回 值: 无
 ***************************************************************/
void iot_thread(void *args)
{
    uint8_t mac_address[12] = {0x00, 0xdc, 0xb6, 0x90, 0x01, 0x00, 0};

    char ssid[32] = ROUTE_SSID;         // wifi名
    char password[32] = ROUTE_PASSWORD; // wifi密码
    char mac_addr[32] = {0};

    FlashInit();
    VendorSet(VENDOR_ID_WIFI_MODE, "STA", 3);                           // 配置为Wifi STA模式
    VendorSet(VENDOR_ID_MAC, mac_address, 6);                           // 多人同时做该实验，请修改各自不同的WiFi MAC地址
    VendorSet(VENDOR_ID_WIFI_ROUTE_SSID, ssid, sizeof(ssid));           // 设置Wi-Fi SSID
    VendorSet(VENDOR_ID_WIFI_ROUTE_PASSWD, password, sizeof(password)); // 设置Wi-Fi密码

reconnect:
    SetWifiModeOff();          // 关闭当前的Wi-Fi连接
    int ret = SetWifiModeOn(); // 尝试打开Wi-Fi连接
    if (ret != 0)
    {
        printf("wifi connect failed,please check wifi config and the AP!\n");
        return;
    }
    lcd_set_network_state(true);

    tcp_client_init(); // 客户端初始化
    tcp_receive_data();
}
